﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetworkIndexer.Core.Service;
using NetworkIndexer.Data.Repositories;
using NetworkIndexer.Data.DomainModels;
using NetworkIndexer.Data.Repositories.Concrete;
using NetworkIndexer.Core.Service.Concrete;
using System.IO;
using NetworkIndexer.Data;

namespace NetworkIndexer.Core.Repositories.Concrete
{
    public class IndexingRepository : IIndexingRepository
    {
        private IDataAccess _dataAccess;
        private IShareService _shareService;
        private IFileSystemDataAccess _fileSystemDataAccess;
        private List<ShareDetails> _networkShareCache;

        public IndexingRepository(IDataAccess dataAccess, IShareService shareService, IFileSystemDataAccess fileSystemDataAccess)
        {
            _dataAccess = dataAccess;
            _shareService = shareService;
            _fileSystemDataAccess = fileSystemDataAccess;
            _networkShareCache = dataAccess.GetNetworkShareCache().ToList();
        }

        public IList<ShareDetails> Index(IList<string> computers, string searchExtensions, bool completeRefresh)
        {
            if (completeRefresh)
                _dataAccess.ClearCache();

            var allShares = new List<ShareDetails>();
            foreach (var computer in computers)
            {
                var shares = _networkShareCache.Where(i => i.ComputerIP == computer);

                if (shares.Count() > 0)
                {
                    foreach (var share in shares)
                    {

                        var shareDetails = new ShareDetails
                        {
                            ShareId = share.ShareId,
                            ComputerIP = share.ComputerIP,
                            SharePath = share.SharePath,
                            files = new List<string>()
                        };
                        PopulateFiles(shareDetails, allShares, searchExtensions);
                    }
                }
                else
                {
                    var refreshedShare = _shareService.GetShares(computer);

                    foreach (var share in refreshedShare)
                    {
                        if (share.ToString().Contains("$"))
                            continue;
                        var shareDetails = new ShareDetails
                        {
                            ShareId = Guid.NewGuid(),
                            ComputerIP = computer,
                            SharePath = share.ToString(),
                            files = new List<string>()
                        };
                        PopulateFiles(shareDetails, allShares, searchExtensions);
                        _dataAccess.AddShareToCache(shareDetails);
                    }

                }

            }
            return allShares;
        }


        /// <summary>
        /// Populates the shares from the share details
        /// </summary>
        /// <param name="shareDetails"></param>
        /// <param name="allShares"></param>
        /// <param name="searchExtensions"></param>
        private void PopulateFiles(ShareDetails shareDetails, List<ShareDetails> allShares, string searchExtensions)
        {
            try
            {               
                var files = _fileSystemDataAccess.GetFiles(shareDetails.SharePath, searchExtensions);                    
                foreach (var file in files)
                {
                    shareDetails.files.Add(file);
                }
                shareDetails.IsShareAccessible = true;
            }
            catch
            {
                //Might be permission error 
                shareDetails.IsShareAccessible = false;
            }
            allShares.Add(shareDetails);
        }


    }
}
